﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Library.HttpTools;
using Library.Logging;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace iNotesNotification
{
    public partial class iNotesForm : Form, ILog
    {
        private const int TIMER_INTERVAL = 1000;

        private iNotesController _notesController;
        private bool _isInEvent = false;
        private bool _needSettingsUpdate = false;
        private string _lastInterfaceType = string.Empty;
        private int _eventMode = 0;
        private TimeSpan _mailCheckInterval;
        private DateTime _lastMailCheck = DateTime.MinValue;
        private bool _isPlayingSound = false;

        public iNotesForm()
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CustomValidation);

            this.Icon = iNotesNotification.Properties.Resources.NotNotes;
            InitializeComponent();
            this.notifyIcon.Icon = iNotesNotification.Properties.Resources.NotNotes;
            
            
            timerRefresh.Interval = TIMER_INTERVAL;
            _mailCheckInterval = TimeSpan.FromSeconds(60);
        }

        private void Settings_Load(object sender, EventArgs e)
        {
            iNotesConfig conf = iNotesConfig.Instance;
            if (!conf.Exists)
            {
                this.tabControl1.SelectedIndex = 1;
            }

            _notesController = iNotesController.Instance;

            BindGrid();
            UpdateTooltip();

            _mailCheckInterval = TimeSpan.FromSeconds(iNotesConfig.Instance.MailCheckInterval);
            if (conf.StartOnApplicationStartup)
            {
                this.timerRefresh.Start();
                UpdateTimerStatusLabel();
            }

        }

        private void BindGrid()
        {
            this.dataGridViewMail.Rows.Clear();

            foreach (iNotesMessage msg in _notesController.Mailbox)
            {
                dataGridViewMail.Rows.Insert(0, 1);
                DataGridViewRow row = dataGridViewMail.Rows[0];
                row.Cells[0].Value = msg.Date;
                row.Cells[1].Value = msg.Sender;
                row.Cells[2].Value = msg.Subject;
                row.Tag = msg.UniqueID;
            }
        }

        private void UpdateMailbox()
        {
            iNotesConfig conf = iNotesConfig.Instance;
            if (conf.Exists && !_isInEvent)
            {
                _isInEvent = true;
                try
                {
                    if (_eventMode == 0)
                    {
                        if (_needSettingsUpdate)
                        {
                            _mailCheckInterval = TimeSpan.FromSeconds(iNotesConfig.Instance.MailCheckInterval);

                            BindGrid();
                            UpdateTooltip();

                            _needSettingsUpdate = false;
                        }
                        else if (DateTime.Now > (_lastMailCheck + _mailCheckInterval))
                        {
                            _eventMode = 1;
                            _notesController.StartAsyncRefresh();
                        }
                    }
                    else if (_eventMode == 1)
                    {
                        if (_notesController.IsAsyncRefreshCompleted)
                        {
                            if (_notesController.AsyncRefreshResult)
                            {
                                _notesController.RefreshAfterAsync();
                                if (_notesController.Mailbox.NewMessageCount > 0)
                                {
                                    BindGrid();

                                    StringBuilder sb = new StringBuilder();
                                    sb.Append(_notesController.Mailbox.NewMessageCount.ToString()).AppendLine(" new messages...");
                                    int idx = 0;
                                    foreach (iNotesMessage message in _notesController.Mailbox.NewMessages)
                                    {
                                        sb.AppendLine(message.Sender + " " + message.Subject);
                                        if (idx >= 4) break;
                                        else idx++;
                                    }
                                    PlaySoundAsync();
                                    this.notifyIcon.ShowBalloonTip(10, "iNotes Notification", sb.ToString(), ToolTipIcon.Info);
                                    _notesController.Mailbox.MarkAsRead();
                                }
                                UpdateTooltip();
                            }
                            _lastMailCheck = DateTime.Now;
                            UpdateTimerStatusLabel();
                            _eventMode = 0;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Program.LogException(ex);
                }
                _isInEvent = false;
            }
        }

        private void timerRefresh_Tick(object sender, EventArgs e)
        {
            UpdateMailbox();
        }

        private static bool CustomValidation(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
        {
            return true;
        }

        private void buttonOk_Click(object sender, EventArgs e)
        {
            this.iNotesSettingsControl1.Save();
            this.WindowState = FormWindowState.Minimized;
        }

        private void buttonExit_Click(object sender, EventArgs e)
        {
            timerRefresh.Stop();
            Application.Exit();
        }

        private void Settings_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }

        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void launchINotesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            iNotesController.LaunchBrowser_Inbox();
        }

        private void dataGridViewMail_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            string msg = dataGridViewMail.Rows[e.RowIndex].Tag as String;
            if (msg != null)
            {
                iNotesController.LaunchBrowser_Email(msg);
            }
        }

        private void viewMailboxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            // Open New Mail Message?
        }

        private void notifyIcon_BalloonTipClosed(object sender, EventArgs e)
        {
            // Mark as Read?
        }

        private void label1_Click(object sender, EventArgs e)
        {
            _mailCheckInterval = TimeSpan.FromSeconds(iNotesConfig.Instance.MailCheckInterval);

            if (this.timerRefresh.Enabled)
            {
                timerRefresh.Stop();
            }
            else
            {
                UpdateMailbox();
                timerRefresh.Start();
            }

            UpdateTimerStatusLabel();
        }

        private void iNotesSettingsControl1_SettingsSaved(object sender, EventArgs e)
        {
            this._needSettingsUpdate = true;
        }

        private void UpdateTooltip()
        {
            StringBuilder sb = new StringBuilder();
            iNotesMessage latest = _notesController.Mailbox.LatestEmail;
            if (latest != null)
            {
                
                sb.Append(latest.Date.ToString("MM-dd hh:mm")).Append("\n")
                    .Append(
                        ((latest.Sender.Length > 20) ? (latest.Sender.Substring(0, 17) + "...") : latest.Sender)
                    ).Append("\n")
                    .Append(
                        ((latest.Subject.Length > 30) ? (latest.Subject.Substring(0, 27) + "...") : latest.Subject)
                    );
            }
            else
            {
                sb.AppendLine("iNotes Notification Tool");
            }
            this.notifyIcon.Text = sb.ToString();
        }

        private void UpdateTimerStatusLabel()
        {
            if (this.timerRefresh.Enabled)
            {
                if (_lastMailCheck > DateTime.MinValue)
                {
                    label1.Text = "Running (Last updated on " + _lastMailCheck.ToString() + ")";
                }
                else
                {
                    label1.Text = "Running";
                }
                label1.ForeColor = Color.Green;
            }
            else
            {
                label1.Text = "Stopped";
                label1.ForeColor = Color.Red;
            }
        }

        private void PlaySoundAsync()
        {
            if (!_isPlayingSound)
            {
                _isPlayingSound = true;

                System.Threading.ParameterizedThreadStart ts = new System.Threading.ParameterizedThreadStart(PlaySound);
                AsyncCallback ac = new AsyncCallback(PlaySoundFinished);
                Object state = new Object();
                ts.BeginInvoke(iNotesConfig.Instance.SoundPath, ac, state);
            }
        }

        private void PlaySound(object file)
        {
            string sfile = file as String;
            if (string.IsNullOrEmpty(sfile))
            {
                System.Media.SystemSounds.Beep.Play();
            }
            else
            {
                FileInfo fi = new FileInfo(sfile);
                if (fi.Exists)
                {
                    try
                    {
                        using (System.Media.SoundPlayer sp = new System.Media.SoundPlayer(fi.ToString()))
                        {
                            sp.PlaySync();
                            sp.Dispose();
                        }
                    }
                    catch
                    {
                        System.Media.SystemSounds.Beep.Play();
                    }
                }
                else
                {
                    System.Media.SystemSounds.Beep.Play();
                }
            }
        }

        private void PlaySoundFinished(IAsyncResult result)
        {
            if (result.IsCompleted) 
            {
                _isPlayingSound = false;
            }
        }
        
        //

        #region LOGGING - FOR DEBUGGING LATER!
        //private bool _isNewLine = true;
        public void Write(string text, params object[] args)
        {
            /*if (_isNewLine) textBoxLog.AppendText(DateTime.Now.ToString() + ": ");
            if (args.Length == 0)
            {
                textBoxLog.AppendText(text);
            }
            else
            {
                textBoxLog.AppendText(string.Format(text, args));
            }
            _isNewLine = false;*/
        }

        public void WriteLine(string text, params object[] args)
        {
            /*if (_isNewLine) textBoxLog.AppendText(DateTime.Now.ToString() + ": ");
            if (args.Length == 0)
            {
                textBoxLog.AppendText(text);
            }
            else
            {
                textBoxLog.AppendText(string.Format(text, args));
            }
            textBoxLog.AppendText(Environment.NewLine);
            _isNewLine = true;*/
        }

        public void WriteLine(Exception ex)
        {
            //WriteLine(ex.Message + ":" + ex.StackTrace);
        }
        #endregion

    }
}
